﻿using Candy.Infrastructure;
using Candy.Model;
using Candy.Web.Data;
using GalaSoft.MvvmLight.Command;
using System.Collections.ObjectModel;
using System.Linq;

namespace Candy.ViewModel
{
    public class ProjectsViewModel : AuthRequiredViewModelBase
    {
        private bool _isBusy;
        public bool IsBusy
        {
            get
            {
                return _isBusy;
            }
            set
            {
                _isBusy = value;
                _load.RaiseCanExecuteChanged();

                if (_isBusy == true)
                    base.ReportProgress();
                else
                    base.FinishProgress();
                RaisePropertyChanged("IsBusy");

            }
        }

        public int NumberOfProjectsLeft
        {
            get
            {
                if (Projects != null && _userManger.AuthenticatedUser != null)
                    return _userManger.AuthenticatedUser.AllowedProjectCount - Projects.Count(x=>x.Role == "Owner");
                else
                    return 0;
            }
        }



        private ObservableCollection<ProjectEntityViewModel> _projects;
        public ObservableCollection<ProjectEntityViewModel> Projects
        {
            get
            {
                return _projects;
            }
            set
            {
                _projects = value;
                RaisePropertyChanged("Projects");
                RaisePropertyChanged("NumberOfProjectsLeft");
         
            }
        }

        private ObservableCollection<ProjectEntityViewModel> _otherProjects;
        public ObservableCollection<ProjectEntityViewModel> OtherProjects
        {
            get
            {
                return _otherProjects;
            }
            set
            {
                _otherProjects = value;
                RaisePropertyChanged("OtherProjects");
            }
        }

        private bool _publicProjectsVisible;
        public bool PublicProjectsVisible
        {
            get
            {
                if (IsInDesignMode)
                    return true;
                return _publicProjectsVisible;
            }
            set
            {
                _publicProjectsVisible = value;
                RaisePropertyChanged("PublicProjectsVisible");
            }
        }

        INavigationService _navigationService;
        IDataService _dataService;
        public ProjectsViewModel(IDataService dataService, INavigationService navigationService, IUserManager userMananger)
            : base(navigationService, userMananger)
        {
            _dataService = dataService;
            _navigationService = navigationService;
            _userManger = userMananger;
            _userManger.LoggedIn += (s,a)=>
                {
                    RaisePropertyChanged("NumberOfProjectsLeft");
                    RaisePropertyChanged("CanCreateProject");
                };

            if (IsInDesignMode)
            {

                Projects = new ObservableCollection<ProjectEntityViewModel>()
                {
                   new ProjectEntityViewModel(_dataService, _navigationService, _userManger,  new ProjectDto { Name = "Test 1", Description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent quis ligula at justo placerat hendrerit. Morbi nisl eros, dictum et fringilla at, consectetur vel leo.", Owner="jaha" }),
                  new ProjectEntityViewModel(_dataService,_navigationService, _userManger,   new ProjectDto { Name = "Test 2", Description = "sdsf sfasdfasb vrsthgsdfbsdf", Owner="jaha" }),
                  new ProjectEntityViewModel(_dataService, _navigationService, _userManger,  new ProjectDto { Name = "Test 3", Description = "sdsf sfasdfasb vrsthgsdfbsdf", Owner="jaha" })
                  
                };
                OtherProjects = new ObservableCollection<ProjectEntityViewModel>()
                {
                   new ProjectEntityViewModel(_dataService,_navigationService, _userManger,  new ProjectDto { Name = "Test 4", Description = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent quis ligula at justo placerat hendrerit. Morbi nisl eros, dictum ", Owner="jaha" }),
                  new ProjectEntityViewModel(_dataService, _navigationService, _userManger,  new ProjectDto { Name = "Test 5", Description = "sdsf sfasdfasb vrsthgsdfbsdf", Owner="jaha" }),
                  new ProjectEntityViewModel( _dataService,_navigationService, _userManger,  new ProjectDto { Name = "Test 6", Description = "sdsf sfasdfasb vrsthgsdfbsdf", Owner="jaha" })
                  
                };


            }
            else
            {
                Projects = new ObservableCollection<ProjectEntityViewModel>();
                OtherProjects = new ObservableCollection<ProjectEntityViewModel>();
            }
        }


        protected override void OnLoggedIn()
        {

            if (_loadPending)
                Load.Execute(null);
        }

        protected override void OnLoggedOut()
        {

        }

        private RelayCommand _load;
        public RelayCommand Load
        {
            get
            {
                return _load ?? (_load = new RelayCommand(ExecLoad, CanLoad));
            }
        }

        /// <summary>
        /// Checks whether the Load command is executable
        /// </summary>
        private bool CanLoad()
        {
            return !_isBusy;
        }


        private bool _loadPending;
        /// <summary>
        /// Executes the Load command 
        /// </summary>
        private void ExecLoad()
        {
            if (CheckAuthentication())
            {
                IsBusy = true;

                //  var query = DataAccess.Instance.DataContext.GetProjectsQuery();
                _dataService.LoadProjectListAsync(op =>
                      {
                          IsBusy = false;
                          if (op.HasError)
                          {
                              base.HandleDomainError(op, "Loading projects failed. Please try again.");
                          }
                          else
                          {
                              foreach (var p in op.Entities.OrderBy(x => x.Name).Select(x => new ProjectEntityViewModel(_dataService, _navigationService, _userManger, x)))
                              {
                                  
                                  if (p.UserCanLoad)
                                  {
                                      if (Projects.Any(x => x.Entity.Id == p.Entity.Id) == false)
                                          Projects.Add(p);
                                  }
                                  else
                                  {
                                      if (OtherProjects.Any(x => x.Entity.Id == p.Entity.Id) == false)
                                          OtherProjects.Add(p);
                                  }
                              }

                             
                          }
                          RaisePropertyChanged("NumberOfProjectsLeft");
                          CreateNewProject.RaiseCanExecuteChanged();
                      });

            }
            else
            {
                _loadPending = true;
            }
        }



        private RelayCommand _createNewProject;
        public RelayCommand CreateNewProject
        {
            get
            {
                return _createNewProject ?? (_createNewProject = new RelayCommand(ExecCreateNewProject, CanCreateNewProject));
            }
        }

        /// <summary>
        /// Checks whether the CreateNewProject command is executable
        /// </summary>
        private bool CanCreateNewProject()
        {
            return NumberOfProjectsLeft > 0;
        }

        /// <summary>
        /// Executes the CreateNewProject command 
        /// </summary>
        private void ExecCreateNewProject()
        {
            _navigationService.Navigate(NavigationTargets.CreateProject);
        }



        private RelayCommand _showPublicProjects;
        public RelayCommand ShowPublicProjects
        {
            get
            {
                return _showPublicProjects ?? (_showPublicProjects = new RelayCommand(ExecShowPublicProjects, CanShowPublicProjects));
            }
        }

        /// <summary>
        /// Checks whether the ShowPublicProjects command is executable
        /// </summary>
        private bool CanShowPublicProjects()
        {
            return true;
        }

        /// <summary>
        /// Executes the ShowPublicProjects command 
        /// </summary>
        private void ExecShowPublicProjects()
        {
            PublicProjectsVisible = true;
        }




    }
}
